/*************************************************
 Copyright (C), 2018, NanJu Tech. Co., Ltd.
 Author:       wunan
 Version:      1.0
 Date:         2018/11/10
 Description:  
 Others:       
 History:      
 *************************************************/
package com.yantong.aspect;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yantong.result.ResultVo;
import com.yantong.service.MemberService;
import com.yantong.annotation.Auth;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.Base64Utils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;

@Aspect
@Component
public class AuthAspect {
    public static final String authorization = "Authorization";
    @Autowired
    private MemberService memberService;
    @Autowired
    private StringRedisTemplate redisTemplate;
    private static final Logger logger = LoggerFactory.getLogger(AuthAspect.class);

    @Pointcut("@annotation(com.yantong.annotation.Auth)")
    public void authPointCut() {}

    @Around("authPointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes()).getRequest();//获取request
//        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder
//                .getRequestAttributes()).getResponse();//获取response
        String token = request.getHeader("Authorization");

        if ((token == null) || (token.isEmpty())) {
        	token = request.getParameter("Authorization");
        }

        if( "dehua".equals( token ) ){
            return joinPoint.proceed();
        }

        if ((token == null) || (token.isEmpty())) {
            return ResultVo.error("无接口访问权限");
        }

        String tokenString;
        try {
            tokenString = new String(Base64Utils.decodeFromString(token), StandardCharsets.UTF_8);
        } catch (IllegalArgumentException e) {
            return ResultVo.error(401,"无效的访问令牌");
        }

        JSONObject authToken = JSON.parseObject(tokenString);
        String id = authToken.getString("id");
        String oid = authToken.getString("oid");
        String sign = authToken.getString("sign");

        String mid = redisTemplate.opsForValue().get(token);

        if(!id.equals(mid)){
            return ResultVo.error(401, "token已失效，请重新登录");
        }

        MethodSignature ms = (MethodSignature) joinPoint.getSignature();
        Method method = ms.getMethod();
        Auth auth = method.getAnnotation(Auth.class);

        if (auth.arg() < 0) {
            return joinPoint.proceed();
        }

        Object[] arguments = joinPoint.getArgs();
        Object memberId = arguments[auth.arg()];

        if (!String.valueOf(memberId).equals(id)) {
            return ResultVo.error("数据访问权限认证失败");
        }

        // 执行方法
        return joinPoint.proceed();
    }
}
